home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_87 / output43.pas < prev    next >
Pascal/Delphi Source File  |  1995-01-01  |  15KB  |  520 lines

  1. UNIT OutPut43;
  2.  
  3. INTERFACE
  4.  
  5. USES Vid43;
  6.  
  7. TYPE
  8.   AoW = ARRAY[0..32750] OF WORD;
  9.   PAoW = ^AoW;
  10.  
  11.   PWindow = ^TWindow;
  12.   TWindow = RECORD
  13.     x, y, w, h : INTEGER;
  14.     col        : STRING[8];
  15.     vis, forz,
  16.     act        : BOOLEAN;
  17.   END;
  18.  
  19. CONST
  20.   pwAttr : BYTE = $62;
  21.  
  22.  
  23.  
  24.  
  25.  
  26. PROCEDURE ClearScreen;
  27. FUNCTION  BoxByte          (b: BYTE)        : CHAR;
  28. FUNCTION  ByteBox          (b: CHAR)        : BYTE;
  29. PROCEDURE PutWindow        (VAR w: TWindow);
  30. PROCEDURE PutWindowBigFrame(VAR w: TWindow);
  31.  
  32.  
  33. FUNCTION  ParseCoords    (x, y: WORD)                     : WORD;
  34. PROCEDURE DirectWriteAttr(offs: WORD; s: STRING; a: BYTE);
  35. PROCEDURE DirectWrite    (offs: WORD; s: STRING);
  36. PROCEDURE DirectWriteBig (offs: WORD; VAR s: STRING);
  37. PROCEDURE PutAttrs       (offs, n: WORD; a: BYTE);
  38. PROCEDURE PutAttrsMask   (offs, n: WORD; a, m: BYTE);
  39. FUNCTION  GetAsciiInScr  (offs: WORD)                     : CHAR;
  40. PROCEDURE RectAttr       (offs, w, h: WORD; a: BYTE);
  41. PROCEDURE RectAttrMask   (offs, w, h: WORD; a, m: BYTE);
  42. PROCEDURE PutRotulo      (offs: WORD; s: STRING; a: BYTE);
  43.  
  44.  
  45. FUNCTION  SaveWindow  (VAR p: PAoW; x, y, w, h: WORD) : BOOLEAN;
  46. PROCEDURE StoreWindow     (p: PAoW; x, y, w, h: WORD);
  47. PROCEDURE RestoreWindow   (p: PAoW);
  48. PROCEDURE DoneWindow      (p: PAoW);
  49. FUNCTION  SavedWindowSize (p: PAoW)                   : WORD;
  50.  
  51.  
  52.  
  53.  
  54. IMPLEMENTATION
  55.  
  56. USES Heaps;
  57.  
  58.  
  59.  
  60.  
  61. PROCEDURE ClearScreen; ASSEMBLER;
  62.   ASM
  63.         MOV     AX,ScrSegment
  64.         MOV     ES,AX
  65.         MOV     CX,ScreenWords
  66.         MOV     DI,ScrOffset
  67.         MOV     AX,$0120
  68.         CLD
  69.         REP STOSW
  70.   END;
  71.  
  72.  
  73.  
  74. FUNCTION  ParseCoords(x, y: WORD) : WORD; ASSEMBLER;
  75.   ASM
  76.         MOV     AX,y
  77.         MOV     BX,80*2
  78.         MUL     BX
  79.         ADD     AX,x
  80.         ADD     AX,x
  81.         ADD     AX,ScrOffset
  82.   END;
  83.  
  84.  
  85.  
  86.  
  87. PROCEDURE DirectWriteAttr(offs: WORD; s: STRING; a: BYTE); ASSEMBLER;
  88.   ASM
  89.         MOV     BX,offs
  90.         MOV     AX,ScrSegment
  91.         MOV     ES,AX
  92.         PUSH    DS
  93.         LDS     SI,s
  94.         MOV     AH,a
  95.         MOV     CL,[DS:SI]
  96. @@lp:    AND     CL,CL
  97.          JZ      @@fin
  98.          INC     SI
  99.          MOV     AL,[DS:SI]
  100.          MOV     [ES:BX],AX
  101.          INC     BX
  102.          INC     BX
  103.          DEC     CL
  104.          JMP     @@lp
  105. @@fin:  POP     DS
  106.   END;
  107.  
  108.  
  109. PROCEDURE DirectWrite(offs: WORD; s: STRING); ASSEMBLER;
  110.   ASM
  111.         MOV     BX,offs
  112.         MOV     AX,ScrSegment
  113.         MOV     ES,AX
  114.         PUSH    DS
  115.         LDS     SI,s
  116.         MOV     CL,[DS:SI]
  117. @@lp:    AND     CL,CL
  118.          JZ      @@fin
  119.          INC     SI
  120.          MOV     AL,[DS:SI]
  121.          MOV     [ES:BX],AL
  122.          INC     BX
  123.          INC     BX
  124.          DEC     CL
  125.          JMP     @@lp
  126. @@fin:  POP     DS
  127.   END;
  128.  
  129.  
  130.  
  131. PROCEDURE DirectWriteBig(offs: WORD; VAR s: STRING);
  132.   CONST
  133.     Num1:STRING[10] = #000#001#002#003#004#005#006#007#008#009;
  134.     Num2:STRING[10] = #224#225#226#227#228#227#224#229#224#231;
  135.                       { A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z }
  136.     Let1:STRING[26] = #010#011#012#013#005#005#014#015#016#017#018#019#020#021#000#011#000#011#022#016#024#024#024#023#023#007;
  137.     Let2:STRING[26] = #230#232#239#232#233#234#224#230#225#227#235#233#230#230#224#234#240#235#227#229#224#236#237#238#229#028;
  138.   VAR
  139.     s1, s2 : STRING[80];
  140.     I      : WORD;
  141.   BEGIN
  142.     s1[0] := s[0];
  143.     s2[0] := s[0];
  144.     FOR i := 1 TO Length(s) DO BEGIN
  145.       IF           (s[i] >= '0') AND (s[i] <= '9')  THEN BEGIN
  146.         s1[i] := Num1[ORD(s[i]) - ORD('0') + 1];
  147.         s2[i] := Num2[ORD(s[i]) - ORD('0') + 1];
  148.       END ELSE IF ((s[i] >= 'A') AND (s[i] <= 'Z')) OR
  149.                   ((s[i] >= 'a') AND (s[i] <= 'z')) THEN BEGIN
  150.         s1[i] := Let1[ORD(UPCASE(s[i])) - ORD('A') + 1];
  151.         s2[i] := Let2[ORD(UPCASE(s[i])) - ORD('A') + 1];
  152.       END ELSE IF s[i] = '-' THEN BEGIN
  153.         s1[i] := ' ';
  154.         s2[i] := #029;
  155.       END ELSE IF s[i] = '#' THEN BEGIN
  156.         s1[i] := #026;
  157.         s2[i] := #025;
  158.       END ELSE IF s[i] = '=' THEN BEGIN
  159.         s1[i] := #027;
  160.         s2[i] := '-';
  161.       END ELSE BEGIN
  162.         s1[i] := ' ';
  163.         s2[i] := ' ';
  164.       END;
  165.     END;
  166.     DirectWrite(offs,   s1);
  167.     DirectWrite(offs + ScreenBytesX, s2);
  168.   END;
  169.  
  170.  
  171.  
  172.  
  173. PROCEDURE PutAttrs(offs, n: WORD; a: BYTE); ASSEMBLER;
  174.   ASM
  175.         MOV     BX,offs
  176.         MOV     AX,ScrSegment
  177.         MOV     ES,AX
  178.         INC     BX
  179.         MOV     AL,a
  180.         MOV     CX,n
  181.         AND     CX,CX
  182.         JZ      @@fin
  183. @@lp:    MOV    [ES:BX],AL
  184.          INC    BX
  185.          INC    BX
  186.          LOOP   @@lp
  187. @@fin:  
  188.   END;
  189.  
  190.  
  191.  
  192.  
  193. PROCEDURE PutAttrsMask(offs, n: WORD; a, m: BYTE); ASSEMBLER;
  194.   ASM
  195.         MOV     BX,offs
  196.         MOV     AX,ScrSegment
  197.         MOV     ES,AX
  198.         INC     BX
  199.         MOV     AL,a
  200.         MOV     CX,n
  201.         AND     CX,CX
  202.         MOV     AH,m
  203.         JZ      @@fin
  204. @@lp:    AND    [ES:BX],AH
  205.          OR     [ES:BX],AL
  206.          INC    BX
  207.          INC    BX
  208.          LOOP   @@lp
  209. @@fin:  
  210.   END;
  211.  
  212.  
  213.  
  214.  
  215. FUNCTION GetAsciiInScr(offs: WORD) : CHAR; ASSEMBLER;
  216.   ASM
  217.         MOV     BX,offs
  218.         MOV     AX,ScrSegment
  219.         MOV     ES,AX
  220.         MOV     AL,[ES:BX]
  221.   END;
  222.  
  223.  
  224.  
  225.  
  226. FUNCTION BoxByte(b: BYTE) : CHAR;
  227.   CONST
  228.     boxes : STRING[48] = '░¼»└½│┌├«┘─┴┐┤┬┼░¼»╚½╠╔╟«╝╦░╗░╤░░¼»╚½╣╔░«╝╩╧╗╢░░';
  229.   BEGIN
  230.     BoxByte := boxes[b+1];
  231.   END;
  232.  
  233.  
  234.  
  235.  
  236. FUNCTION ByteBox(b: CHAR) : BYTE;
  237.   VAR
  238.     i : WORD;
  239.   BEGIN
  240.     FOR i := 0 TO 47 DO
  241.       IF b = BoxByte(i) THEN BEGIN
  242.         ByteBox := i;
  243.         EXIT;
  244.       END;
  245.     ByteBox := 0;
  246.   END;
  247.  
  248.  
  249.  
  250.  
  251. PROCEDURE PutWindowBigFrame(VAR w: TWindow);
  252.   VAR
  253.     s      : STRING[80];
  254.     i      : WORD;
  255.     ch     : CHAR;
  256.     offs   : WORD;
  257.   BEGIN
  258.     WITH w DO BEGIN
  259.       offs := ParseCoords(x, y);
  260.       s[0] := CHR(w);
  261.  
  262.       IF h = 1 THEN BEGIN
  263.  
  264.         s[1] := BoxByte(ByteBox(GetAsciiInScr(offs)) OR 2);
  265.         FOR i := 2 TO w-1 DO
  266.           s[i] :=  BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2)) OR $A);
  267.         s[w] := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2)) OR 8);
  268.         DirectWriteAttr(offs, s, pwAttr);
  269.  
  270.       END ELSE IF w = 1 THEN BEGIN
  271.  
  272.         ch := BoxByte(ByteBox(GetAsciiInScr(offs)) OR 4);
  273.         DirectWriteAttr(offs,         ch, pwAttr);
  274.         ch := BoxByte(ByteBox(GetAsciiInScr(offs + (h - 1)*ScreenBytesX)) OR 1);
  275.         DirectWriteAttr(offs + (h - 1)*ScreenBytesX,         ch, pwAttr);
  276.         FOR i := 2 TO h - 1 DO BEGIN
  277.           ch := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*ScreenBytesX)) OR 5);
  278.           DirectWriteAttr(offs + (i - 1)*ScreenBytesX,         ch, pwAttr);
  279.         END;
  280.  
  281.       END ELSE BEGIN
  282.  
  283.         s[1] := BoxByte(ByteBox(GetAsciiInScr(offs)) AND $F OR $16);
  284.         IF col[1] = #0 THEN
  285.           FOR i := 2 TO w-1 DO
  286.             s[i] :=  BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2)) AND $F OR $1A)
  287.         ELSE
  288.           FOR i := 2 TO w-1 DO
  289.             s[i] :=  BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2)) AND $B OR $1A);
  290.         s[w] := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2)) AND $F OR $2C);
  291.         DirectWriteAttr(offs, s, pwAttr);
  292.  
  293.         s[1] := BoxByte(ByteBox(GetAsciiInScr(offs + (h - 1)*ScreenBytesX)) AND $F OR $13);
  294.         IF col[1] = #0 THEN
  295.           FOR i := 2 TO w-1 DO
  296.             s[i] := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2 + (h - 1)*ScreenBytesX)) AND $F OR $2A)
  297.         ELSE
  298.           FOR i := 2 TO w-1 DO
  299.             s[i] := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2 + (h - 1)*ScreenBytesX)) AND $E OR $2A);
  300.         s[w] := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2 + (h - 1)*ScreenBytesX)) AND $F OR $29);
  301.         DirectWriteAttr(offs + (h - 1)*ScreenBytesX, s, pwAttr);
  302.  
  303.         s[0] := CHR(w - 2);
  304.         FillChar(s[1], w-2, ' ');
  305.         FOR i := 2 TO h - 1 DO BEGIN
  306.           IF col[1] <> #0 THEN BEGIN
  307.             DirectWriteAttr(offs + 2 + (i - 1)*ScreenBytesX,     s,   BYTE(col[1]));
  308.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*ScreenBytesX)) AND $D OR $15);
  309.             DirectWriteAttr(offs + (i - 1)*ScreenBytesX,         ch, pwAttr);
  310.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX)) AND $7 OR $25);
  311.             DirectWriteAttr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX, ch, pwAttr);
  312.           END ELSE BEGIN
  313.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*ScreenBytesX)) AND $F OR $15);
  314.             DirectWriteAttr(offs + (i - 1)*ScreenBytesX,         ch, pwAttr);
  315.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX)) AND $F OR $25);
  316.             DirectWriteAttr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX, ch, pwAttr);
  317.           END;
  318.         END;
  319.       END;
  320.     END;
  321.   END;
  322.  
  323.  
  324.  
  325.  
  326. PROCEDURE PutWindow(VAR w: TWindow);
  327.   VAR
  328.     s      : STRING[80];
  329.     i      : WORD;
  330.     ch     : CHAR;
  331.     offs   : WORD;
  332.   BEGIN
  333.     WITH w DO BEGIN
  334.       offs := ParseCoords(x, y);
  335.  
  336.       s[0] := CHR(w);
  337.  
  338.       IF h = 1 THEN BEGIN
  339.  
  340.         s[1] := BoxByte(ByteBox(GetAsciiInScr(offs)) OR 2);
  341.         FOR i := 2 TO w-1 DO
  342.           s[i] :=  BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2)) OR $A);
  343.         s[w] := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2)) OR 8);
  344.         DirectWriteAttr(offs, s, pwAttr);
  345.  
  346.       END ELSE IF w = 1 THEN BEGIN
  347.  
  348.         ch := BoxByte(ByteBox(GetAsciiInScr(offs)) OR 4);
  349.         DirectWriteAttr(offs,         ch, pwAttr);
  350.         ch := BoxByte(ByteBox(GetAsciiInScr(offs + (h - 1)*ScreenBytesX)) OR 1);
  351.         DirectWriteAttr(offs + (h - 1)*ScreenBytesX,         ch, pwAttr);
  352.         FOR i := 2 TO h - 1 DO BEGIN
  353.           ch := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*ScreenBytesX)) OR 5);
  354.           DirectWriteAttr(offs + (i - 1)*ScreenBytesX,         ch, pwAttr);
  355.         END;
  356.  
  357.       END ELSE BEGIN
  358.  
  359.         s[1] := BoxByte(ByteBox(GetAsciiInScr(offs)) OR 6);
  360.         IF col[1] = #0 THEN
  361.           FOR i := 2 TO w-1 DO
  362.             s[i] :=  BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2)) OR $A)
  363.         ELSE
  364.           FOR i := 2 TO w-1 DO
  365.             s[i] :=  BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2)) AND $3B OR $A);
  366.         s[w] := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2)) OR $C);
  367.         DirectWriteAttr(offs, s, pwAttr);
  368.  
  369.         s[1] := BoxByte(ByteBox(GetAsciiInScr(offs + (h - 1)*ScreenBytesX)) OR 3);
  370.         IF col[1] = #0 THEN
  371.           FOR i := 2 TO w-1 DO
  372.             s[i] := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2 + (h - 1)*ScreenBytesX)) OR $A)
  373.         ELSE
  374.           FOR i := 2 TO w-1 DO
  375.             s[i] := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*2 + (h - 1)*ScreenBytesX)) AND $3E OR $A);
  376.         s[w] := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2 + (h - 1)*ScreenBytesX)) OR 9);
  377.         DirectWriteAttr(offs + (h - 1)*ScreenBytesX, s, pwAttr);
  378.  
  379.         s[0] := CHR(w - 2);
  380.         FillChar(s[1], w-2, ' ');
  381.         FOR i := 2 TO h - 1 DO BEGIN
  382.           IF col[1] <> #0 THEN BEGIN
  383.             DirectWriteAttr(offs + 2 + (i - 1)*ScreenBytesX,     s,   BYTE(col[1]));
  384.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*ScreenBytesX)) AND $3D OR 5);
  385.             DirectWriteAttr(offs + (i - 1)*ScreenBytesX,         ch, pwAttr);
  386.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX)) AND $37 OR 5);
  387.             DirectWriteAttr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX, ch, pwAttr);
  388.           END ELSE BEGIN
  389.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (i - 1)*ScreenBytesX)) OR 5);
  390.             DirectWriteAttr(offs + (i - 1)*ScreenBytesX,         ch, pwAttr);
  391.             ch := BoxByte(ByteBox(GetAsciiInScr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX)) OR 5);
  392.             DirectWriteAttr(offs + (w - 1)*2 + (i - 1)*ScreenBytesX, ch, pwAttr);
  393.           END;
  394.         END;
  395.       END;
  396.     END;
  397.   END;
  398.  
  399.  
  400.  
  401. PROCEDURE RectAttr(offs, w, h: WORD; a: BYTE);
  402.   VAR
  403.     i : WORD;
  404.   BEGIN
  405.     FOR i := 1 TO h DO
  406.       PutAttrs(offs + (i - 1)*ScreenBytesX, w, a);
  407.   END;
  408.  
  409.  
  410.  
  411. PROCEDURE RectAttrMask(offs, w, h: WORD; a, m: BYTE);
  412.   VAR
  413.     i : WORD;
  414.   BEGIN
  415.     FOR i := 1 TO h DO
  416.       PutAttrsMask(offs + (i - 1)*ScreenBytesX, w, a, m);
  417.   END;
  418.  
  419.  
  420.  
  421. PROCEDURE PutRotulo(offs: WORD; s: STRING; a: BYTE);
  422.   VAR
  423.     i : WORD;
  424.     b : BYTE;
  425.   BEGIN
  426.  
  427.     IF offs > ScrOffset THEN BEGIN
  428.       b := ByteBox(GetAsciiInScr(offs-2));
  429.       IF b <> 0 THEN DirectWrite(offs-2, BoxByte(b AND $D));
  430.     END;
  431.  
  432.     IF offs + Length(s)*2 < ScreenBytes + ScrOffset - 1 THEN BEGIN
  433.       b := ByteBox(GetAsciiInScr(offs+2*Length(s)));
  434.       IF b <> 0 THEN DirectWrite(offs+2*Length(s), BoxByte(b AND 7));
  435.     END;
  436.  
  437.     IF offs >= ScrOffset + ScreenBytesX THEN
  438.       FOR i := 1 TO Length(s) DO BEGIN
  439.         b := ByteBox(GetAsciiInScr(offs + (i - 1)*2 - ScreenBytesX));
  440.         IF b <> 0 THEN DirectWrite(offs + (i - 1)*2 - ScreenBytesX, BoxByte(b AND $B));
  441.       END;
  442.  
  443.     IF offs < ScreenBytes - ScreenBytesX THEN
  444.       FOR i := 1 TO Length(s) DO BEGIN
  445.         b := ByteBox(GetAsciiInScr(offs + (i - 1)*2 + ScreenBytesX));
  446.         IF b <> 0 THEN DirectWrite(offs + (i - 1)*2 + ScreenBytesX, BoxByte(b AND $E));
  447.       END;
  448.  
  449.     DirectWriteAttr(offs, s, a);
  450.  
  451.   END;
  452.  
  453.  
  454.  
  455.  
  456. FUNCTION SaveWindow(VAR p: PAoW; x, y, w, h: WORD) : BOOLEAN;
  457.   VAR
  458.     i, j,
  459.     beg  : WORD;
  460.   BEGIN
  461.     SaveWindow := TRUE;
  462.  
  463.     IF p = NIL THEN
  464.       FullHeap.HGetMem(POINTER(p), w*h*2 + 2*3)
  465.     ELSE IF (p^[1] * p^[2]) <> (w * h) THEN BEGIN
  466.       SaveWindow := FALSE;
  467.       EXIT;
  468.     END;
  469.  
  470.     beg := y * 160 + x*2;
  471.     p^[0] := beg;
  472.     p^[1] := w;
  473.     p^[2] := h;
  474.     FOR i := 0 TO h-1 DO
  475.       FOR j := 0 TO w-1 DO
  476.         p^[3 + i*w + j] := MEMW[ScrSegment:ScrOffset+(beg + i*160 + j*2)];
  477.   END;
  478.  
  479.  
  480. PROCEDURE StoreWindow(p: PAoW; x, y, w, h: WORD);
  481.   VAR
  482.     i, j,
  483.     beg  : WORD;
  484.   BEGIN
  485.     beg := y * 160 + x*2;
  486.     p^[0] := beg;
  487.     p^[1] := w;
  488.     p^[2] := h;
  489.     FOR i := 0 TO h-1 DO
  490.       FOR j := 0 TO w-1 DO
  491.         p^[3 + i*w + j] := MEMW[ScrSegment:ScrOffset+(beg + i*160 + j*2)];
  492.   END;
  493.  
  494.  
  495. PROCEDURE RestoreWindow(p: PAoW);
  496.   VAR
  497.     i, j : WORD;
  498.   BEGIN
  499.     FOR i := 0 TO p^[2]-1 DO
  500.       FOR j := 0 TO p^[1]-1 DO
  501.         MEMW[ScrSegment:ScrOffset+(p^[0] + i*160 + j*2)] := p^[3 + i*p^[1] + j];
  502.   END;
  503.  
  504.  
  505. PROCEDURE DoneWindow(p: PAoW);
  506.   BEGIN
  507.     FullHeap.HFreeMem(POINTER(p), p^[1]*p^[2]*2 + 2*3);
  508.   END;
  509.  
  510.  
  511. FUNCTION SavedWindowSize(p: PAoW) : WORD;
  512.   BEGIN
  513.     SavedWindowSize := p^[1]*p^[2]*2 + 2*3;
  514.   END;
  515.  
  516.  
  517.  
  518.  
  519. END.
  520.